View Javadoc

1   // InterfaceImpl.java, created Wed Dec 11 11:59:03 2002 by mcmartin
2   // Copyright (C) 2001-3 John Whaley <jwhaley@alum.mit.edu>
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
4   package joeq.ClassLib.Common;
5   
6   import java.util.HashMap;
7   import java.util.Iterator;
8   import java.util.Vector;
9   import java.lang.reflect.Constructor;
10  import joeq.Bootstrap.MethodInvocation;
11  import joeq.Bootstrap.SinglePassBootImage;
12  import joeq.Class.PrimordialClassLoader;
13  import joeq.Class.jq_Class;
14  import joeq.Class.jq_InstanceField;
15  import joeq.Class.jq_Member;
16  import joeq.Class.jq_Method;
17  import joeq.Class.jq_StaticField;
18  import joeq.Class.jq_Type;
19  import joeq.Class.jq_Reference.jq_NullType;
20  import joeq.ClassLib.ClassLibInterface;
21  import joeq.Compiler.Quad.BytecodeToQuad.jq_ReturnAddressType;
22  import joeq.Main.jq;
23  import joeq.Memory.CodeAddress;
24  import joeq.Memory.HeapAddress;
25  import joeq.Memory.StackAddress;
26  import joeq.Runtime.ObjectTraverser;
27  import joeq.Runtime.Reflection;
28  import joeq.Runtime.TypeCheck;
29  import joeq.Scheduler.jq_Thread;
30  import jwutil.util.Assert;
31  import jwutil.util.Convert;
32  
33  /***
34   * InterfaceImpl
35   *
36   * @author  John Whaley <jwhaley@alum.mit.edu>
37   * @version $Id: InterfaceImpl.java 1941 2004-09-30 03:37:06Z joewhaley $
38   */
39  public abstract class InterfaceImpl implements Interface {
40  
41      /*** Creates new Interface */
42      public InterfaceImpl() {}
43  
44      public java.util.Iterator getImplementationClassDescs(joeq.UTF.Utf8 desc) {
45          if (ClassLibInterface.USE_JOEQ_CLASSLIB && (desc.toString().startsWith("Ljava/") ||
46                                                      desc.toString().startsWith("Lsun/misc/"))) {
47              joeq.UTF.Utf8 u = joeq.UTF.Utf8.get("Ljoeq/ClassLib/Common/"+desc.toString().substring(1));
48              return java.util.Collections.singleton(u).iterator();
49          }
50          return java.util.Collections.EMPTY_SET.iterator();
51      }
52      
53      public abstract ObjectTraverser getObjectTraverser();
54      
55      public static class CommonObjectTraverser extends ObjectTraverser {
56          //public static CommonObjectTraverser INSTANCE = new CommonObjectTraverser();
57          protected CommonObjectTraverser() { }
58          protected static final java.util.Set nullStaticFields = new java.util.HashSet();
59          protected static final java.util.Set nullInstanceFields = new java.util.HashSet();
60          protected static final java.util.Map mappedObjects = new java.util.HashMap();
61          public static /*final*/ boolean IGNORE_THREAD_LOCALS = true;
62          public void initialize() {
63              //nullStaticFields.add(Unsafe._remapper_object);
64              nullStaticFields.add(CodeAddress._FACTORY);
65              nullStaticFields.add(HeapAddress._FACTORY);
66              nullStaticFields.add(StackAddress._FACTORY);
67              nullStaticFields.add(SinglePassBootImage._DEFAULT);
68              nullStaticFields.add(Reflection._obj_trav);
69              Reflection.registerNullStaticFields(nullStaticFields);
70              nullStaticFields.add(joeq.Allocator.DefaultCodeAllocator._default_allocator);
71              jq_Class k = PrimordialClassLoader.getJavaLangSystem();
72              nullStaticFields.add(k.getOrCreateStaticField("in", "Ljava/io/InputStream;"));
73              nullStaticFields.add(k.getOrCreateStaticField("out", "Ljava/io/PrintStream;"));
74              nullStaticFields.add(k.getOrCreateStaticField("err", "Ljava/io/PrintStream;"));
75              nullStaticFields.add(k.getOrCreateStaticField("props", "Ljava/util/Properties;"));
76              k = PrimordialClassLoader.getJavaLangClassLoader();
77              nullStaticFields.add(k.getOrCreateStaticField("loadedLibraryNames",
78                                                            "Ljava/util/Vector;"));
79              nullStaticFields.add(k.getOrCreateStaticField("systemNativeLibraries",
80                                                            "Ljava/util/Vector;"));
81              nullStaticFields.add(k.getOrCreateStaticField("nativeLibraryContext",
82                                                            "Ljava/util/Stack;"));
83              k = PrimordialClassLoader.getJavaLangRefFinalizer();
84              // todo: static fields in "java.lang.ref.Finalizer" need help.
85              k = (jq_Class)PrimordialClassLoader.loader.getOrCreateBSType("Ljoeq/Main/jq;");
86              nullStaticFields.add(k.getOrCreateStaticField("on_vm_startup",
87                                                            "Ljava/util/List;"));
88              k = PrimordialClassLoader.getJavaLangClass();
89              // TODO: signers
90              nullInstanceFields.add(k.getOrCreateInstanceField("signers", "[Ljava/lang/Object;"));
91              // TODO: protection_domain
92              nullInstanceFields.add(k.getOrCreateInstanceField("protection_domain", "Ljava/security/ProtectionDomain;"));
93              k = (jq_Class) PrimordialClassLoader.loader.getOrCreateBSType("Ljava/util/zip/ZipFile;");
94              nullInstanceFields.add(k.getOrCreateInstanceField("raf", "Ljava/io/RandomAccessFile;"));
95              nullInstanceFields.add(k.getOrCreateInstanceField("entries", "Ljava/util/Hashtable;"));
96              nullInstanceFields.add(k.getOrCreateInstanceField("cenpos", "J"));
97              nullInstanceFields.add(k.getOrCreateInstanceField("pos", "J"));
98              k = (jq_Class) PrimordialClassLoader.loader.getOrCreateBSType("Ljoeq/Class/PrimordialClassLoader$ZipFileElement;");
99              nullInstanceFields.add(k.getOrCreateInstanceField("entries", "Ljava/util/Map;"));
100             k = (jq_Class) PrimordialClassLoader.loader.getOrCreateBSType("Ljoeq/Class/PrimordialClassLoader$PathElement;");
101             nullInstanceFields.add(k.getOrCreateInstanceField("entries", "Ljava/util/Set;"));
102         }
103 
104         public java.lang.Object mapStaticField(jq_StaticField f) {
105             if (nullStaticFields.contains(f)) {
106                 return null;
107             }
108             return NO_OBJECT;
109         }
110         public java.lang.Object mapInstanceField(java.lang.Object o,
111                                                  jq_InstanceField f) {
112             if (nullInstanceFields.contains(f)) {
113                 return null;
114             }
115             jq_Class c = f.getDeclaringClass();
116             String fieldName = f.getName().toString();
117             if (c == PrimordialClassLoader.getJavaLangClass()) {
118                 if (fieldName.equals("jq_type"))
119                     return Reflection.getJQType((java.lang.Class) o);
120             } else if (c == jq_Type._class) {
121                 if (o == jq_NullType.NULL_TYPE)
122                     return null;
123                 if (o == jq_ReturnAddressType.INSTANCE)
124                     return null;
125                 if (!joeq.Class.jq_Class.USE_CLASS_OBJECT_FIELD &&
126                     fieldName.equals("class_object"))
127                     return Reflection.getJDKType((jq_Type) o);
128             } else if (c == PrimordialClassLoader.getJavaLangReflectField()) {
129                 if (fieldName.equals("jq_field")) {
130                     Object r = Reflection.getJQMember((java.lang.reflect.Field) o);
131                     return r;
132                 }
133             } else if (c == PrimordialClassLoader.getJavaLangReflectMethod()) {
134                 if (fieldName.equals("jq_method"))
135                     return Reflection.getJQMember((java.lang.reflect.Method) o);
136             } else if (
137                 c == PrimordialClassLoader.getJavaLangReflectConstructor()) {
138                 if (fieldName.equals("jq_init"))
139                     return Reflection.getJQMember((Constructor) o);
140             } else if (!joeq.Class.jq_Member.USE_MEMBER_OBJECT_FIELD &&
141                        (c == PrimordialClassLoader.loader.getBSType("Ljoeq/Class/jq_Member;"))) {
142                 if (fieldName.equals("member_object")) {
143                     // reflection returns different objects every time!
144                     // cache one and use it from now on.
145                     Object o2 = mappedObjects.get(o);
146                     if (o2 != null)
147                         return o2;
148                     mappedObjects.put(o, o2 = Reflection.getJDKMember((jq_Member) o));
149                     return o2;
150                 }
151             } else if (c == PrimordialClassLoader.getJavaLangThread()) {
152                 if (fieldName.equals("jq_thread")) {
153                     Object o2 = mappedObjects.get(o);
154                     if (o2 != null)
155                         return o2;
156                     mappedObjects.put(o, o2 = new jq_Thread((Thread) o));
157                     return o2;
158                 }
159                 /****
160                 if (fieldName.equals("threadLocals"))
161                     return java.util.Collections.EMPTY_MAP;
162                 if (fieldName.equals("inheritableThreadLocals"))
163                     return java.util.Collections.EMPTY_MAP;
164                 ***/
165             } else if (c == PrimordialClassLoader.getJavaLangClassLoader()) {
166                 if (o == PrimordialClassLoader.loader) {
167                     if (fieldName.equals("parent"))
168                         return null;
169                     if (fieldName.equals("desc2type"))
170                         return getInstanceFieldValue_reflection(o, lookupField(PrimordialClassLoader.class, "bs_desc2type"));
171                 } else if (fieldName.equals("desc2type")) {
172                     Object o2 = mappedObjects.get(o);
173                     if (o2 != null)
174                         return o2;
175                     Class c2 = Reflection.getJDKType(c);
176                     Vector classes = (Vector) getInstanceFieldValue_reflection(o, lookupField(c2, "classes"));
177                     HashMap desc2type = new HashMap();
178                     Iterator i = classes.iterator();
179                     while (i.hasNext()) {
180                         Class c3 = (Class) i.next();
181                         jq_Type t = Reflection.getJQType(c3);
182                         desc2type.put(t.getDesc(), t);
183                     }
184                     mappedObjects.put(o, desc2type);
185                     return desc2type;
186                 }
187             } else if (c == PrimordialClassLoader.getJavaLangRefFinalizer()) {
188                 // null out all fields of finalizer objects.
189                 return null;
190             } else if (TypeCheck.isAssignable(c, PrimordialClassLoader.getJavaLangThrowable())) {
191                 if (fieldName.equals("backtrace")) {
192                     // sun jvm crashes when using reflection on java.lang.Throwable.backtrace
193                     return null;
194                     /*
195                     Object o2 = mapped_objects.get(o);
196                     if (o2 != null) return o2;
197                     mapped_objects.put(o, o2 = new int[0]);
198                     return o2;
199                     */
200                 }
201             } else if (c == PrimordialClassLoader.loader.getBSType("Ljava/util/zip/Inflater;")) {
202                 // Inflater objects are reinitialized on VM startup.
203                 return null;
204             }
205 
206             return NO_OBJECT;
207         }
208         
209         public java.lang.Object mapValue(java.lang.Object o) {
210             if (o == ClassLoader.getSystemClassLoader()) {
211                 return PrimordialClassLoader.loader;
212             }
213             else
214             if (o instanceof java.util.zip.ZipFile) {
215                 Object o2 = mappedObjects.get(o);
216                 if (o2 != null) return o;
217                 mappedObjects.put(o, o);
218                 String name = ((java.util.zip.ZipFile)o).getName();
219             
220                 // we need to reopen the ZipFile on VM startup
221                 if (jq.on_vm_startup != null) {
222                     Object[] args = { o, name };
223                     jq_Method zip_open = ClassLibInterface._class.getOrCreateStaticMethod("init_zipfile_static", "(Ljava/util/zip/ZipFile;Ljava/lang/String;)V");
224                     MethodInvocation mi = new MethodInvocation(zip_open, args);
225                     jq.on_vm_startup.add(mi);
226                     System.out.println("Reopening zip file on joeq startup: "+name);
227                 }
228             }
229             else
230             if (o instanceof java.util.zip.Inflater) {
231                 Object o2 = mappedObjects.get(o);
232                 if (o2 != null) return o;
233                 mappedObjects.put(o, o);
234                 boolean nowrap = false; // TODO: how do we know?
235                 
236                 // we need to reinitialize the Inflater on VM startup
237                 if (jq.on_vm_startup != null) {
238                     Object[] args = { o, Convert.getBoolean(nowrap) };
239                     jq_Method zip_open = ClassLibInterface._class.getOrCreateStaticMethod("init_inflater_static", "(Ljava/util/zip/Inflater;Z)V");
240                     MethodInvocation mi = new MethodInvocation(zip_open, args);
241                     jq.on_vm_startup.add(mi);
242                     System.out.println("Reinitializing inflater on joeq startup: "+o);
243                 }
244             }
245             return o;
246         }
247     }
248     
249     public java.lang.Class createNewClass(joeq.Class.jq_Type f) {
250         Assert._assert(jq.RunningNative);
251         return joeq.ClassLib.Common.java.lang.Class.createNewClass(f);
252     }
253     
254     public java.lang.reflect.Constructor createNewConstructor(joeq.Class.jq_Initializer f) {
255         Assert._assert(jq.RunningNative);
256         return joeq.ClassLib.Common.java.lang.reflect.Constructor.createNewConstructor(f);
257     }
258     
259     public void initNewConstructor(java.lang.reflect.Constructor dis, joeq.Class.jq_Initializer f) {
260         Assert._assert(jq.RunningNative);
261         java.lang.Object o = dis;
262         joeq.ClassLib.Common.java.lang.reflect.Constructor.initNewConstructor((joeq.ClassLib.Common.java.lang.reflect.Constructor)o, f);
263     }
264     
265     public java.lang.reflect.Field createNewField(joeq.Class.jq_Field f) {
266         Assert._assert(jq.RunningNative);
267         return joeq.ClassLib.Common.java.lang.reflect.Field.createNewField(f);
268     }
269     
270     public void initNewField(java.lang.reflect.Field dis, joeq.Class.jq_Field f) {
271         Assert._assert(jq.RunningNative);
272         java.lang.Object o = dis;
273         joeq.ClassLib.Common.java.lang.reflect.Field.initNewField((joeq.ClassLib.Common.java.lang.reflect.Field)o, f);
274     }
275     
276     public java.lang.reflect.Method createNewMethod(joeq.Class.jq_Method f) {
277         Assert._assert(jq.RunningNative);
278         return joeq.ClassLib.Common.java.lang.reflect.Method.createNewMethod(f);
279     }
280     
281     public void initNewMethod(java.lang.reflect.Method dis, joeq.Class.jq_Method f) {
282         Assert._assert(jq.RunningNative);
283         java.lang.Object o = dis;
284         joeq.ClassLib.Common.java.lang.reflect.Method.initNewMethod((joeq.ClassLib.Common.java.lang.reflect.Method)o, f);
285     }
286     
287     public joeq.Class.jq_Field getJQField(java.lang.reflect.Field f) {
288         Assert._assert(jq.RunningNative);
289         java.lang.Object o = f;
290         return ((joeq.ClassLib.Common.java.lang.reflect.Field)o).jq_field;
291     }
292     
293     public joeq.Class.jq_Initializer getJQInitializer(java.lang.reflect.Constructor f) {
294         Assert._assert(jq.RunningNative);
295         java.lang.Object o = f;
296         return ((joeq.ClassLib.Common.java.lang.reflect.Constructor)o).jq_init;
297     }
298     
299     public joeq.Class.jq_Method getJQMethod(java.lang.reflect.Method f) {
300         Assert._assert(jq.RunningNative);
301         java.lang.Object o = f;
302         return ((joeq.ClassLib.Common.java.lang.reflect.Method)o).jq_method;
303     }
304     
305     public joeq.Class.jq_Type getJQType(java.lang.Class k) {
306         Assert._assert(jq.RunningNative);
307         java.lang.Object o = k;
308         return ((joeq.ClassLib.Common.java.lang.Class)o).jq_type;
309     }
310     
311     public joeq.Class.jq_Type getOrCreateType(java.lang.ClassLoader cl, joeq.UTF.Utf8 desc) {
312         Assert._assert(jq.RunningNative);
313         java.lang.Object o = cl;
314         return ((joeq.ClassLib.Common.java.lang.ClassLoader)o).getOrCreateType(desc);
315     }
316     
317     public void unloadType(java.lang.ClassLoader cl, joeq.Class.jq_Type t) {
318         Assert._assert(jq.RunningNative);
319         java.lang.Object o = cl;
320         ((joeq.ClassLib.Common.java.lang.ClassLoader)o).unloadType(t);
321     }
322     
323     public void init_zipfile(java.util.zip.ZipFile dis, java.lang.String name) throws java.io.IOException {
324         Assert._assert(jq.RunningNative);
325         java.lang.Object o = dis;
326         ((joeq.ClassLib.Common.java.util.zip.ZipFile)o).__init__(name);
327     }
328     
329     public void init_inflater(java.util.zip.Inflater dis, boolean nowrap) throws java.io.IOException {
330         Assert._assert(jq.RunningNative);
331         java.lang.Object o = dis;
332         ((joeq.ClassLib.Common.java.util.zip.Inflater)o).__init__(nowrap);
333     }
334     
335     public void initializeSystemClass() throws java.lang.Throwable {
336         Assert._assert(jq.RunningNative);
337         joeq.ClassLib.Common.java.lang.System.initializeSystemClass();
338     }
339     
340     public joeq.Scheduler.jq_Thread getJQThread(java.lang.Thread t) {
341         Assert._assert(jq.RunningNative);
342         java.lang.Object o = t;
343         return ((joeq.ClassLib.Common.java.lang.Thread)o).jq_thread;
344     }    
345 
346     /*
347     public void open(java.io.RandomAccessFile dis, java.lang.String name, boolean writeable) throws java.io.FileNotFoundException {
348         jq.Assert(jq.RunningNative);
349         java.lang.Object o = dis;
350         ((joeq.ClassLib.Common.java.io.RandomAccessFile)o).open(name, writeable);
351     }
352     */
353     
354 }